package com.thoughtworks.impersonator.http.message;

import static org.hamcrest.CoreMatchers.is;
import static org.junit.Assert.assertThat;

import org.jboss.netty.buffer.ChannelBuffers;
import org.jboss.netty.handler.codec.http.DefaultHttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponse;
import org.jboss.netty.handler.codec.http.HttpResponseStatus;
import org.jboss.netty.handler.codec.http.HttpVersion;
import org.junit.Test;

import com.thoughtworks.impersonator.http.message.RawResponse;
import com.thoughtworks.impersonator.http.message.builder.ResponseBuilder;

public class RawResponseTest {

    private static final String LINE_TERMINATOR = "\r\n";

    @Test
    public void shouldIdentifyResponseCode() {
        ResponseBuilder builder = new ResponseBuilder().withResponseCode(200);

        RawResponse response = new RawResponse(builder.toReader());

        assertThat(response.getStatusCode(), is(200));
    }

    @Test
    public void shouldParseResponseReasonPhrase() {
        ResponseBuilder builder = new ResponseBuilder().withReasonPhrase("OK");

        RawResponse response = new RawResponse(builder.toReader());

        assertThat(response.getReasonPhrase(), is("OK"));
    }

    @Test
    public void shouldParseResponseHeaders() {
        ResponseBuilder builder = new ResponseBuilder().withHeader("Connection", "Keep-Alive");

        RawResponse response = new RawResponse(builder.toReader());

        assertThat(response.getHeader("Connection"), is("Keep-Alive"));
    }

    @Test
    public void shouldParseResponseBody() {
        ResponseBuilder builder = new ResponseBuilder().withBody("w00t" + LINE_TERMINATOR);

        RawResponse response = new RawResponse(builder.toReader());

        assertThat(response.getBody(), is("w00t" + LINE_TERMINATOR));
    }

    @Test
    public void shouldChangeContentLengthWhenBodyChanges() {
        RawResponse response = new RawResponse(new ResponseBuilder().withBody("w00t").toReader());
        assertThat(response.getHeader("Content-Length"), is("4"));

        response.setBody("to a longer string");

        assertThat(response.getHeader("Content-Length"), is("18"));
    }

    @Test
    public void shouldReturnAProperlyFormattedResponse() {
        String expectedResponse = new StringBuilder().append("HTTP/1.1 200 OK").append(LINE_TERMINATOR).append(
                "Content-Length: 6").append(LINE_TERMINATOR).append(LINE_TERMINATOR).append("w00t").append(
                LINE_TERMINATOR).toString();

        ResponseBuilder builder = new ResponseBuilder().withoutHeaders();
        builder.withResponseCode(200).withReasonPhrase("OK").withBody("w00t" + LINE_TERMINATOR);

        RawResponse response = new RawResponse(builder.toReader());

        assertThat(response.toString(), is(expectedResponse));
    }

    @Test
    public void shouldBuildResponseFromHttpServletResponse() throws Exception {
        HttpResponse httpResponse = new DefaultHttpResponse(HttpVersion.HTTP_1_1, HttpResponseStatus.OK);
        httpResponse.addHeader("hot", "bubbles");
        httpResponse.setContent(ChannelBuffers.copiedBuffer("w00t" + LINE_TERMINATOR, "utf-8"));

        RawResponse response = new RawResponse(httpResponse);

        String expectedResponse = new StringBuilder().append("HTTP/1.1 200 OK").append(LINE_TERMINATOR).append(
                "Content-Length: 6").append(LINE_TERMINATOR).append("hot: bubbles").append(LINE_TERMINATOR).append(
                LINE_TERMINATOR).append("w00t").append(LINE_TERMINATOR).toString();
        assertThat(response.toString(), is(expectedResponse));
    }

}
